package com.lixinlei.security.api.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lixinlei.security.api.entity.AuditLog;
import com.lixinlei.security.api.dao.AuditLogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

@Component
public class AuditLogInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private AuditLogRepository auditLogRepository;

    /**
     * 在业务方法执行之前执行
     * postHandle 是在业务方法执行成功之后执行
     * @param request
     * @param response
     * @param handler
     * @return 如果返回 false，就可以拒绝请求的执行，直接返回
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        System.out.println(3);

        AuditLog log = new AuditLog();
        log.setMethod(request.getMethod());
        log.setPath(request.getRequestURI());

        // 保存日志
        auditLogRepository.save(log);

        request.setAttribute("auditLogId", log.getId());
        return true;
    }

    /**
     * 业务方法处理成功与否都会执行
     * @param request
     * @param response
     * @param handler
     * @param ex 如果业务方法处理成功，就不会有这个异常
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex)
            throws Exception {

        Long auditLogId = (Long) request.getAttribute("auditLogId");
        AuditLog log = auditLogRepository.findById(auditLogId).get();

        // 就算业务方法执行失败，这里的 status 还是 200，然后会跳到一个 /error 的路径，这个的 status 是 500
        log.setStatus(response.getStatus());

        // 更新日志
        auditLogRepository.save(log);
    }

}
